// BluetoothManager.cpp
#include "BluetoothManager.h"

BluetoothManager::BluetoothManager(ConfigManager &cfg)
    : config(cfg), btStarted(false), isClassicMode(false)
#if CLASSIC_BT_SUPPORTED
      ,
      serialBT(nullptr)
#endif
#if BLE_SUPPORTED
      ,
      pServer(nullptr), pService(nullptr), pTxCharacteristic(nullptr), pRxCharacteristic(nullptr),
      deviceConnected(false), oldDeviceConnected(false)
#endif
{
    // 构造函数初始化
}

BluetoothManager::~BluetoothManager()
{
    stopBT();
}

bool BluetoothManager::begin()
{
    BluetoothConfig &btConfig = config.getBluetoothConfig();

    if (strlen(btConfig.deviceName) == 0)
    {
        DEBUG_PRINTLN("Bluetooth device name not set");
        return false;
    }

    if (btConfig.bleEnabled && BLE_SUPPORTED)
    {
        return startBLE(btConfig.deviceName);
    }
    else if (btConfig.classicEnabled && CLASSIC_BT_SUPPORTED)
    {
        return startClassicBT(btConfig.deviceName);
    }

    DEBUG_PRINTLN("No Bluetooth mode enabled or supported");
    return false;
}

bool BluetoothManager::startClassicBT(const char *deviceName)
{
#if CLASSIC_BT_SUPPORTED
    if (!CLASSIC_BT_SUPPORTED)
    {
        DEBUG_PRINTLN("Classic BT not supported on this chip");
        return false;
    }

    if (serialBT != nullptr)
    {
        DEBUG_PRINTLN("Classic BT already started");
        return false;
    }

    serialBT = new BluetoothSerial();

    if (!serialBT->begin(deviceName))
    {
        DEBUG_PRINTLN("Failed to start Classic BT");
        delete serialBT;
        serialBT = nullptr;
        return false;
    }

    btStarted = true;
    isClassicMode = true;
    DEBUG_PRINTLN("Classic BT started: " + String(deviceName));
    return true;
#else
    DEBUG_PRINTLN("Classic BT not available");
    return false;
#endif
}

bool BluetoothManager::startBLE(const char *deviceName)
{
#if BLE_SUPPORTED
    if (!BLE_SUPPORTED)
    {
        DEBUG_PRINTLN("BLE not supported on this chip");
        return false;
    }

    if (btStarted)
    {
        DEBUG_PRINTLN("Bluetooth already started");
        return false;
    }

    try
    {
        BLEDevice::init(deviceName);
        pServer = BLEDevice::createServer();
        pServer->setCallbacks(new MyServerCallbacks(this));

        pService = pServer->createService(SERVICE_UUID);

        pTxCharacteristic = pService->createCharacteristic(
            CHARACTERISTIC_UUID_TX,
            BLECharacteristic::PROPERTY_NOTIFY);

        pRxCharacteristic = pService->createCharacteristic(
            CHARACTERISTIC_UUID_RX,
            BLECharacteristic::PROPERTY_WRITE);

        pRxCharacteristic->setCallbacks(new RxCallbacks(this));

        pService->start();

        BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
        pAdvertising->addServiceUUID(SERVICE_UUID);
        pAdvertising->setScanResponse(true);
        pAdvertising->setMinPreferred(0x06);
        pAdvertising->setMaxPreferred(0x12);
        BLEDevice::startAdvertising();

        btStarted = true;
        isClassicMode = false;
        DEBUG_PRINTLN("BLE started: " + String(deviceName));
        return true;
    }
    catch (...)
    {
        DEBUG_PRINTLN("Failed to start BLE");
        return false;
    }
#else
    DEBUG_PRINTLN("BLE not available");
    return false;
#endif
}

void BluetoothManager::update()
{
#if CLASSIC_BT_SUPPORTED
    if (isClassicMode && serialBT != nullptr && serialBT->hasClient())
    {
        // 处理经典蓝牙数据
        while (serialBT->available())
        {
            char c = serialBT->read();
            // 这里可以添加指令处理逻辑
            Serial.write(c); // 回显到串口
        }
    }
#endif

#if BLE_SUPPORTED
    if (!isClassicMode && btStarted)
    {
        // BLE 连接管理
        if (deviceConnected && !oldDeviceConnected)
        {
            // 新连接建立
            oldDeviceConnected = deviceConnected;
        }

        if (!deviceConnected && oldDeviceConnected)
        {
            // 连接断开，重新开始广播
            delay(500); // 给蓝牙栈一个机会
            pServer->startAdvertising();
            DEBUG_PRINTLN("BLE advertising restarted");
            oldDeviceConnected = deviceConnected;
        }
    }
#endif
}

void BluetoothManager::stopBT()
{
#if CLASSIC_BT_SUPPORTED
    if (serialBT != nullptr)
    {
        serialBT->end();
        delete serialBT;
        serialBT = nullptr;
    }
#endif

#if BLE_SUPPORTED
    if (pServer != nullptr)
    {
        BLEDevice::deinit(true); // true 表示释放资源
        pServer = nullptr;
        pService = nullptr;
        pTxCharacteristic = nullptr;
        pRxCharacteristic = nullptr;
    }
#endif

    btStarted = false;
    isClassicMode = false;
}
String BluetoothManager::getStatus()
{
    if (!btStarted)
        return "Disabled";

    if (isClassicMode)
    {
#if CLASSIC_BT_SUPPORTED
        if (serialBT != nullptr && serialBT->hasClient())
        {
            return "Classic BT - Connected";
        }
        else
        {
            return "Classic BT - Waiting for connection";
        }
#else
        return "Classic BT - Not Supported";
#endif
    }
    else
    {
#if BLE_SUPPORTED
        if (deviceConnected)
        {
            return "BLE - Connected";
        }
        else
        {
            return "BLE - Advertising";
        }
#else
        return "BLE - Not Supported";
#endif
    }
}

bool BluetoothManager::isConnected()
{
    if (!btStarted)
        return false;

    if (isClassicMode)
    {
#if CLASSIC_BT_SUPPORTED
        return serialBT != nullptr && serialBT->hasClient();
#else
        return false;
#endif
    }
    else
    {
#if BLE_SUPPORTED
        return deviceConnected;
#else
        return false;
#endif
    }
}

#if BLE_SUPPORTED
// BLE 回调实现
void BluetoothManager::MyServerCallbacks::onConnect(BLEServer *pServer)
{
    manager->deviceConnected = true;
    manager->oldDeviceConnected = true;
    DEBUG_PRINTLN("BLE Client connected");
}

void BluetoothManager::MyServerCallbacks::onDisconnect(BLEServer *pServer)
{
    manager->deviceConnected = false;
    DEBUG_PRINTLN("BLE Client disconnected");
}

void BluetoothManager::RxCallbacks::onWrite(BLECharacteristic *pCharacteristic)
{
    std::string value = pCharacteristic->getValue();
    if (value.length() > 0)
    {
        DEBUG_PRINT("BLE Received: ");
        for (int i = 0; i < value.length(); i++)
        {
            DEBUG_PRINT(value[i]);
            Serial.write(value[i]); // 转发到串口
        }
        DEBUG_PRINTLN();
    }
}
#endif